// controllers/loginController.cc
#include "loginController.h"

using namespace drogon;
using namespace drogon::orm;

using drogon_model::jol::Users;

void loginController::login(const HttpRequestPtr& req,
                          std::function<void(const HttpResponsePtr&)>&& callback) {
    
    Json::Value requestJson = *req->getJsonObject();
    std::string user_id = requestJson["user_id"].asString();
    std::string password = requestJson["password"].asString();
    
    Json::Value jsonResp;
    if (user_id.empty() || password.empty()) {
        jsonResp.clear();
        jsonResp["error"] = "用户名和密码不能为空";
        auto resp = HttpResponse::newHttpJsonResponse(jsonResp);
        resp->setStatusCode(k400BadRequest);
        callback(resp);
        return;
    }

    auto dbClient = app().getDbClient();
    dbClient->execSqlAsync(
        "SELECT * FROM users WHERE user_id = ?",
        [this, callback, password, jsonResp](const Result& result) mutable {
            
            if (result.empty()) {
                //std::cout << "jafijaf\n";
                jsonResp.clear();
                jsonResp["error"] = "用户不存在";
                auto resp = HttpResponse::newHttpJsonResponse(jsonResp);
                //std::cout << "jafijaf2\n";
                resp->setStatusCode(k401Unauthorized);
                callback(resp);
                return;
            }
            // std::cout << result[0]["user_id"] << "\n";
            //std::string 
            auto user = Users(result[0]);
            //std::cout << *user.getUserId() << "\n";
            auto user_password = *user.getPassword();
            if (!plugins::PasswordUtils::verifyPassword(password, user_password)) {
                jsonResp.clear();
                jsonResp["error"] = "用户名或密码错误";
                auto resp = HttpResponse::newHttpJsonResponse(jsonResp);
                resp->setStatusCode(k401Unauthorized);
                callback(resp);
                return;
            }

            std::string user_id;
            auto userIdPtr = user.getUserId();
            if (userIdPtr != nullptr) {
                user_id = *userIdPtr;
            } else {
                // 抛出异常，说明 userId 为空
                throw std::invalid_argument("createUserResponse: user.getUserId() returned nullptr");
            }
            //std::cout << "1\n";
            // 生成 JWT token
            auto token = jwt::create()
                .set_issuer("auth0")
                .set_type("JWS")
                .set_payload_claim("user_id", jwt::claim(user_id))
                .set_issued_at(std::chrono::system_clock::now())
                .set_expires_at(std::chrono::system_clock::now() + 
                              std::chrono::hours{24})
                .sign(jwt::algorithm::hs256{"your-secret-key"});
            //std::cout << "2\n";
            Json::Value response;
            response["token"] = token;
            //std::cout << "3\n";
            response["user"] = createUserResponse(user);
            //std::cout << "4\n";
            auto resp = HttpResponse::newHttpJsonResponse(response);
            resp->setStatusCode(k200OK);
            callback(resp);
        },
        [callback, jsonResp](const DrogonDbException& e) mutable {
            LOG_ERROR << "Database error: " << e.base().what();
            jsonResp.clear();
            jsonResp["error"] = "服务器内部错误";
            auto resp = HttpResponse::newHttpJsonResponse(jsonResp);
            resp->setStatusCode(k500InternalServerError);
            callback(resp);
        },
        user_id
    );
}

void loginController::logout(const HttpRequestPtr& req,
                           std::function<void(const HttpResponsePtr&)>&& callback) {
    // 如果是 JWT，客户端只需删除 token
    // 如果需要服务端黑名单，可以在这里实现
    Json::Value jsonResp;
    jsonResp["message"] = "退出成功";
    auto resp = HttpResponse::newHttpJsonResponse(jsonResp);
    callback(resp);
}

void loginController::checkAuth(const HttpRequestPtr& req,
                              std::function<void(const HttpResponsePtr&)>&& callback) {
    auto token = req->getHeader("Authorization");
    Json::Value jsonResp;
    if (token.empty() || token.find("Bearer ") != 0) {
        jsonResp["authenticated"] = false;
        auto resp = HttpResponse::newHttpJsonResponse(jsonResp);
        callback(resp);
        return;
    }

    token = token.substr(7); // 移除 "Bearer " 前缀

    try {
        auto decoded = jwt::decode(token);
        auto verifier = jwt::verify()
            .allow_algorithm(jwt::algorithm::hs256{"your-secret-key"})
            .with_issuer("auth0");

        verifier.verify(decoded);

        jsonResp.clear();
        jsonResp["authenticated"] = true;
        auto resp = HttpResponse::newHttpJsonResponse(jsonResp);
        callback(resp);
    } catch (const std::exception& e) {
        jsonResp.clear();
        jsonResp["authenticated"] = false;
        auto resp = HttpResponse::newHttpJsonResponse(jsonResp);
        callback(resp);
    }
}

void loginController::registerPage(const HttpRequestPtr& req,
                                std::function<void(const HttpResponsePtr&)>&& callback) {
    auto resp = HttpResponse::newHttpViewResponse("register.csp");
    callback(resp);
}

void loginController::dashboard(const HttpRequestPtr& req,
                             std::function<void(const HttpResponsePtr&)>&& callback) {
    // 检查用户认证
    auto token = req->getHeader("Authorization");
    if (token.empty()) {
        // 从 cookie 获取 token
        token = req->getCookie("token");
    }

    if (!token.empty()) {
        // 验证 token 并获取用户信息
        HttpViewData data;
        data.insert("user_id", "当前用户"); // 从 token 解码获取实际用户名
        auto resp = HttpResponse::newHttpViewResponse("dashboard.csp", data);
        callback(resp);
    } else {
        // 重定向到登录页
        auto resp = HttpResponse::newRedirectionResponse("/login");
        callback(resp);
    }
}

Json::Value loginController::createUserResponse(const Users& user) {
    Json::Value userJson;
    auto userIdPtr = user.getUserId();
    if (userIdPtr != nullptr) {
        userJson["user_id"] = *userIdPtr;
    } else {
        // 抛出异常，说明 userId 为空
        throw std::invalid_argument("createUserResponse: user.getUserId() returned nullptr");
    }
    return userJson;
}